package src.serverSide;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import src.categoryStructures.Categories;
import src.dataStructures.*;



/**
 * This class stores all the data on the users and items according to ID, and handles 
 * the assignment of new IDs.  
 * @author John Stewart
 */
public class AccountData {
	private HashMap<Integer,Data> datamap = new HashMap<Integer,Data>();
	private int counter = 1;
	
	/**
	 * Creates a new data object at the current counter position.  
	 * @param name The username of the account
	 * @param type The type of the new object
	 * @return The ID of the new user
	 */
	public int newData(String name, DataType type) {
		Data data;
		switch (type) {
			case ITEM: 
				data = new Item(counter, name); 
				break;
			case USER: 
			default: 
				data = new User(counter, name); 
		}
		if (counter == 1) data.permission = 4;
		datamap.put(counter, data);
		counter++;
		return data.id;
	}
	
	/**
	 * This method returns the full information related to the data
	 * @param dataid The ID of the data to return
	 * @param detail The detail to copy over
	 * @return The data object
	 */
	public Data getData(int dataid, DetailLevel detail) {
		if (!datamap.containsKey(dataid)) return new User();
		else return datamap.get(dataid).copy(detail);
	}
	
	/**
	 * This method updates the data object associated with the given object with the new data.
	 * The fields updated depends on the detail modifier in the new data object
	 * @param data The data to use for the update
	 * @return The updated data object
	 */
	public Data setData(Data data) {
		if (!datamap.containsKey(data.id)) return new User();
		else return data.copy(datamap.get(data.id)).copy(data.detail);
	}
	
	/**
	 * Removes the corresponding data from the server
	 * @param userid The ID of the data to remove
	 * @return The name of the data removed
	 */
	public String removeData(int dataid) {
		String name = null;
		if (datamap.containsKey(dataid)) {
			name = datamap.get(dataid).name;
			Data data = datamap.remove(dataid);
			if (data instanceof Item) {
				Item item = (Item) data;
				data = datamap.get(item.authorid);
				if (data instanceof User) {
					List<Integer> itemlist = ((User) data).itemlist;
					for (int i = 0; i < itemlist.size(); i++)
						if (itemlist.get(i) == item.id) 
							itemlist.remove(i);
				}
			}
		}
		return name;
	}
	
	/**
	 * This method sets the permission of the given data object to the value specified
	 * @param dataid The ID of the object to change
	 * @param permission The new permission level
	 * @return The new data object
	 */
	public Data setPermission(int dataid, int permission) {
		if (datamap.containsKey(dataid)) {
			Data data = datamap.get(dataid);
			data.permission = permission;
			return data.copy(DetailLevel.FULL);
		} else return new User();
	}
	
	/**
	 * This method sets the category list inside the given item
	 * @param itemid The ID of the item to look up
	 * @param categories The new categories to set
	 */
	public void setCategories(int itemid, Categories categories) {
		if (datamap.containsKey(itemid) && datamap.get(itemid) instanceof Item) 
			((Item) datamap.get(itemid)).categories = categories.copy();
	}
	
	/**
	 * This method changes the item to read that the given user ID is its parent
	 * @param itemid The ID of the item to change
	 * @param userid The ID of the user to set as the parent
	 */
	public void setParent(int itemid, int userid) {
		Data data = datamap.get(itemid);
		if (data instanceof Item) {
			Item item = (Item) data;
			Data user = datamap.get(userid);
			item.authorid = user.id;
			item.author = user.name;
		}
	}
	
	/**
	 * This method changes the user to have a new item reference
	 * @param userid The ID of the user to change
	 * @param itemid The ID of the item to add
	 */
	public void setChild(int userid, int itemid) {
		Data data = datamap.get(userid);
		if (data instanceof User) {
			User user = (User) data;
			Data item = datamap.get(userid);
			user.itemlist.add(item.id);
		}
		
	}
	
}
